home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 49
/
Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso
/
-serious-
/
misc
/
shellscr
/
src
/
shellscr.e
< prev
Wrap
Text File
|
1999-11-30
|
12KB
|
383 lines
-> ShellScr v1.6 by Kyzer/CSG
-> Creates a fullscreen shell with it's own public screen
-> $VER: ShellScr.e 1.6 (15.09.99)
OPT PREPROCESS,OSVERSION=37
MODULE 'asl', 'diskfont', 'dos/dos', 'dos/dosextens', 'dos/dostags',
'exec/lists', 'exec/nodes', 'graphics/displayinfo', 'graphics/modeid',
'graphics/text', 'intuition/intuition', 'intuition/screens',
'libraries/asl', 'locale', 'utility/tagitem', 'workbench/startup',
'*args', '*clr', '*defarg', '*locale', '*paths'
DEF aslbase=NIL
-> make shortcut to getting locale strings
#define c(x) get_str(catalog, x)
#define DEF_CONSPEC \
'CON:\s//BACKDROP/NOBORDER/NOSIZE/NODRAG/NODEPTH/NOCLOSE/SCREEN\s'
#define DEF_CONSPEC_LEN 71
#define TEMPLATE \
'PUBNAME=NAME,MODEID=ID,DEPTH/N,FONT/K,AUTOSCROLL/S,'+\
'SHANGHAI/S,SCREENTITLE=TITLE,NOTITLE=HIDETITLE/S,'+\
'CONSPEC=WINDOW,COMMANDFILE=FROM,STACKSIZE=STACK/N'
OBJECT myargs
pubname -> chosen public screen name or NIL
modeid -> string referencing mode-id or NIL
depth -> ptr to LONG number or NIL: depth of screen
font -> ptr to font description ('fontname/size') or NIL
autoscroll -> boolean, true (default) = AUTOSCROLL screen
shanghai -> boolean, true = SHANGHAI mode enabled
title -> string: name of titlebar or NIL
notitle -> boolean, zero = show titlebar, non-zero = hide titlebar
conspec -> WINDOW parameter of NewShell
cmdfile -> FROM parameter of NewShell
stacksize -> ptr to LONG number or NIL: size of stack
ENDOBJECT
DEF args:myargs, sig=-1, pubname[32]:STRING, catalog=NIL
RAISE "MEM" IF String()=NIL
RAISE "SYS" IF SystemTagList()<>0
RAISE "def" IF LockPubScreen()=NIL
RAISE "sig" IF AllocSignal()=-1
->-----------------------------------------------------------------------------
PROC main() HANDLE
DEF wbmsg:PTR TO wbstartup, rdargs=NIL, olddir, dir=NIL,
screen=NIL, command, depth=2, stack
-> choose reasonable start directory when launched from Workbench
IF wbmsg := wbmessage
IF dir := DupLock(
IF wbmsg.numargs > 1 THEN wbmsg.arglist[1].lock ELSE GetProgramDir()
) THEN olddir := CurrentDir(dir)
ENDIF
-> initialise localization
IF localebase := OpenLibrary('locale.library', 38)
catalog := OpenCatalogA(NIL, 'shellscr.catalog', NIL)
ENDIF
-> initialise argarray
clr(args, SIZEOF myargs)
args.pubname := StringF(pubname, c(MSG_DEF_PUBNAME), FindTask(NIL))
args.depth := {depth}
-> read arguments with fabulous wb-friendly readargs()
IF (rdargs := readargs(TEMPLATE, args, wbmsg)) = NIL THEN Raise("args")
-> open the screen, and construct the required arguments
command := makecmd(screen := openscr())
-> run the NewShell command to open a new command.
stack := Max(1600, IF args.stacksize THEN Long(args.stacksize) ELSE 4096)
SystemTagList(command, NEW [
NP_PATH, getpath(),
NP_STACKSIZE, stack + 3 AND -4,
SYS_USERSHELL, TRUE,
SYS_ASYNCH, FALSE,
TAG_DONE
])
REPEAT
Wait(Shl(1, sig) OR SIGBREAKF_CTRL_C)
UNTIL CloseScreen(screen)
screen := NIL
EXCEPT DO
-> Errors that deserve an error message to the user are processed here
SELECT exception
-> couldn't allocate memory for strings or such
CASE "MEM"; msg(error(ERROR_NO_FREE_STORE))
-> System() failed
CASE "SYS"; msg(error(0, c(MSG_NEWSHELL_FAILED)))
-> ReadArgs() failed
CASE "args"; msg(error(0, c(MSG_BAD_ARGS)))
-> LockPubScreen() failed
CASE "def"; msg(c(MSG_NO_DEF_SCREEN))
-> OpenScreen() failed
CASE "scr"; exceptioninfo := c(IF (exceptioninfo < 0) OR (exceptioninfo > 7) THEN MSG_UNKNOWN_ERROR ELSE MSG_SCREENERROR + exceptioninfo)
msg(c(MSG_SCREEN_ERROR), {exceptioninfo})
ENDSELECT
-> cleanup
IF screen
REPEAT; UNTIL CloseScreen(screen)
SetDefaultPubScreen(NIL)
ENDIF
IF dir THEN UnLock(CurrentDir(olddir))
IF rdargs THEN FreeArgs(rdargs)
IF sig <> -1 THEN FreeSignal(sig)
IF localebase THEN CloseCatalog(catalog)
CloseLibrary(localebase)
ENDPROC (IF exception THEN 10 ELSE 0)
->-----------------------------------------------------------------------------
PROC makecmd(s:PTR TO screen)
-> create the 'NewShell' command required to open the shell
DEF cmd, cmdformat, sizes, top
-> window-size calculation (see guide)
top := IF args.notitle THEN 0 ELSE IF args.conspec THEN s.barheight+1 ELSE 3
sizes := StringF(String(24), '\d/\d/\d/\d', 0, top, s.width, s.height-top)
-> generate command formatter : 'NewShell [conspec] [FROM cmdfile]'
-> conspec contains two '%s' ('\s') formatters for windowsize and screenname
cmdformat := StringF(
String(
9 +
(IF args.conspec THEN StrLen(args.conspec) ELSE DEF_CONSPEC_LEN) +
(IF args.cmdfile THEN StrLen(args.cmdfile)+6 ELSE 0)
),
'NewShell \s\s\s',
defarg(args.conspec, DEF_CONSPEC),
IF args.cmdfile THEN ' FROM ' ELSE '',
defarg(args.cmdfile, '')
)
-> create final command from format template
cmd := StringF(
String(EstrLen(cmdformat) + EstrLen(sizes) + StrLen(args.pubname)),
cmdformat, sizes, args.pubname
)
ENDPROC cmd
->-----------------------------------------------------------------------------
PROC openscr() HANDLE
-> opens the screen as requested by the user
DEF screen=NIL:PTR TO screen, defscreen=NIL:PTR TO screen,
drawinfo=NIL:PTR TO drawinfo, errorcode, fontdesc, font
-> Find a default screen to read default information about
drawinfo := GetScreenDrawInfo(defscreen := LockPubScreen(NIL))
-> get the required font - or copy the default screen's
fontdesc, font := openfont(defscreen.font)
screen := OpenScreenTagList(NIL, NEW [
SA_ERRORCODE, {errorcode},
-> tags defining the public nature of our screen
SA_PUBNAME, args.pubname,
SA_PUBSIG, sig := AllocSignal(-1),
SA_PUBTASK, FindTask(NIL),
SA_TYPE, PUBLICSCREEN,
SA_DISPLAYID, getmode(args.modeid, GetVPModeID(defscreen.viewport)),
SA_DEPTH, Long(args.depth),
SA_FONT, fontdesc,
SA_AUTOSCROLL, args.autoscroll,
SA_TITLE, defarg(args.title, c(MSG_DEF_TITLE)),
SA_SHOWTITLE, (args.notitle = FALSE),
SA_PENS, IF drawinfo THEN drawinfo.pens ELSE [-1]:INT,
SA_FULLPALETTE, TRUE,
TAG_DONE
])
IF screen = NIL THEN Throw("scr", errorcode)
-> make screen go public, also make it the default pubscreen
PubScreenStatus(screen, PUBLICSCREEN)
SetDefaultPubScreen(args.pubname)
-> enable Shanghai mode if user wants this
IF args.shanghai THEN SetPubScreenModes(SHANGHAI OR SetPubScreenModes(0))
EXCEPT DO
IF font THEN CloseFont(font)
IF drawinfo THEN FreeScreenDrawInfo(defscreen, drawinfo)
IF defscreen THEN UnlockPubScreen(NIL, defscreen)
CloseLibrary(diskfontbase)
CloseLibrary(aslbase)
ReThrow()
ENDPROC screen
->----
PROC openfont(deffont:PTR TO textattr)
DEF fontdesc=NIL:PTR TO textattr, font=NIL:PTR TO textfont, name, size
-> find out the real name/size of our requested (or not) font
name, size := getfont(args.font)
-> if a certain font has been decided, then open it from disk
IF name
IF diskfontbase := OpenLibrary('diskfont.library', 37)
IF font := OpenDiskFont(fontdesc := NEW [name, size, 0, 0]:textattr)
-> tsssk the user if he picked a proportional font
IF font.flags AND FPF_PROPORTIONAL THEN msg(c(MSG_PROPFONT), fontdesc)
ENDIF
ENDIF
ELSE
-> only copy default font if it is fixed-width
IF (deffont.flags AND FPF_PROPORTIONAL)=0
CopyMem(deffont, NEW fontdesc, SIZEOF textattr)
fontdesc.name := StrCopy(String(StrLen(fontdesc.name)), fontdesc.name)
ENDIF
ENDIF
ENDPROC fontdesc, font
->----
PROC getfont(fontname)
-> process font-string (eg 'topaz/11', 'lcd.10', 'flyspeck', '?') and return
-> proper name and size ('topaz.font',11, 'lcd.font',10 ...)
DEF font=NIL, size=8, req:PTR TO fontrequester, valid, n
IF fontname = NIL THEN RETURN NIL
-> ASL font requester if fontname="?" or fontname=""
IF (StrCmp(fontname, '?') OR StrCmp(fontname, ''))
IF openasl()
IF req := AllocAslRequest(ASL_FONTREQUEST, NIL)
IF AslRequest(req, [ASLFO_FIXEDWIDTHONLY, TRUE, TAG_DONE])
font := StrCopy(String(StrLen(req.attr.name)), req.attr.name)
size := req.attr.ysize
ENDIF
FreeAslRequest(req)
ENDIF
ENDIF
ELSE
-> copy fontname so we can (perhaps) modify it
StrCopy(font := String(StrLen(fontname)+5), fontname)
-> look for and remove size from string
-> (in 'myfont/99' or 'myfont.99' format)
IF (n := InStr(font, '/')) = -1 THEN n := InStr(font, '.')
IF n <> -1
-> get size from string (or 8 as default)
size, valid := Val(font+n+1)
IF valid = FALSE THEN size := 8
-> remove size part from string
font[n] := "\0" -> can we guarantee SetStr() to do this?
SetStr(font, n)
ENDIF
-> add '.font' to name if neccessary
IF InStr(font, '.font') = -1 THEN StrAdd(font, '.font')
ENDIF
ENDPROC font, size
->----
PROC getmode(modename, defmode)
-> process string with some form of mode name in it, and return a numeric ID
-> string can take the form of:
-> '' or '?' (cause user choice from ASL screenmode requester)
-> 'PAL:High Res' (named graphic mode)
-> '12345678' (decimal for compatibility with ShellScr 1.2 and previous
-> '0x29000' (hexadecimal spec with C-style number)
-> '$29000' (hexadecimal spec with asm-style number)
-> if parsing fails, it returns the default mode supplied
DEF modeid, req:PTR TO screenmoderequester, ok, valid, dh, ni:nameinfo
IF modename = NIL THEN RETURN defmode
-> ASL screenmode requester when modename='?' or ''
IF (StrCmp(modename, '?') OR StrCmp(modename, ''))
IF openasl()
IF req := AllocAslRequest(ASL_SCREENMODEREQUEST, NIL)
ok := AslRequest(req, NEW [
ASLSM_DOAUTOSCROLL, TRUE,
ASLSM_DODEPTH, TRUE,
ASLSM_INITIALAUTOSCROLL, args.autoscroll,
ASLSM_INITIALDISPLAYDEPTH, Long(args.depth),
ASLSM_INITIALDISPLAYID, defmode,
TAG_DONE
])
FreeAslRequest(req)
IF ok = FALSE THEN Raise("canc") -> 'cancelled requester' exception
PutLong(args.depth, req.displaydepth)
args.autoscroll := req.autoscroll
modeid := req.displayid
msg(c(MSG_MODEID), {modeid})
RETURN modeid
ENDIF
ENDIF
ENDIF
-> compare modename against all named screenmodes in the display database
modeid := INVALID_ID
WHILE (modeid := NextDisplayInfo(modeid)) <> INVALID_ID
IF (modeid AND MONITOR_ID_MASK)
dh := FindDisplayInfo(modeid)
IF GetDisplayInfoData(dh, ni, SIZEOF nameinfo, DTAG_NAME, INVALID_ID)
IF StrCmp(modename, ni.name) THEN RETURN modeid
ENDIF
ENDIF
ENDWHILE
-> otherwise - a numeric ID.
-> change '0xB1AB1A' into '$B1AB1A'
IF StrCmp(modename, '0x', 2); INC modename; modename[] := "$"; ENDIF
-> find the value of the ID.
modeid, valid := Val(modename)
ENDPROC IF valid THEN modeid ELSE defmode
->-----------------------------------------------------------------------------
-> handy little things...
-> message-printer for WB and shell
PROC msg(msg, args=NIL)
IF wbmessage
EasyRequestArgs(NIL, NEW [20, 0, 'ShellScr', msg, c(MSG_OK)], 0, args)
ELSE
Vprintf(msg, args); PutStr('\n')
ENDIF
ENDPROC
-> returns string form of DOS Fault. Can prepend header.
PROC error(error=0, header=NIL)
DEF x
SetStr(x := String((IF header THEN StrLen(header) ELSE 0) + FAULT_MAX + 2),
Fault(defarg(error, IoErr()), header, x, StrMax(x))
)
ENDPROC x
-> open asl.library only once
PROC openasl() IS defarg(aslbase, aslbase := OpenLibrary('asl.library', 38))
CHAR '$VER: ShellScr 1.6 (15.09.99)'